import App from "./App.vue";
import router from "./router";
import { setupStore } from "@/store";
import { getPlatformConfig } from "./config";
import { MotionPlugin } from "@vueuse/motion";
// import { useEcharts } from "@/plugins/echarts";
import { createApp, type Directive } from "vue";
import { useElementPlus } from "@/plugins/elementPlus";
import { injectResponsiveStorage } from "@/utils/responsive";
import { ElNotification } from "element-plus";
import { getToken } from "@/utils/auth";
import websocketClient from "@/utils/notify";
import type { NavigationFailure } from "vue-router";
import notifyRecordApi, {
  type MarkReadPayload
} from "@/api/system/notify/record";

interface SystemNotificationDetail {
  title?: string;
  message?: string;
  route?: string;
  sound?: string;
  payload?: Record<string, any> | null;
  messageId?: number;
  recipientId?: number;
  targetId?: number | string;
  targetType?: string;
}

const registerSystemNotificationHandler = () => {
  const isElectronClient = Boolean(
    (window as any)?.electronAPI?.showNotification
  );

  const globalWindow = window as Window & {
    __notifyHandler__?: EventListener;
    __notifyIpcRegistered__?: boolean;
  };

  if (globalWindow.__notifyHandler__) {
    window.removeEventListener(
      "systemNotification",
      globalWindow.__notifyHandler__
    );
  }

  let audioElement: HTMLAudioElement | null = null;
  const playNotificationSound = (soundUrl: string) => {
    try {
      if (!soundUrl) return;
      if (!audioElement) {
        audioElement = document.createElement("audio");
        audioElement.preload = "auto";
        audioElement.style.display = "none";
        document.body.appendChild(audioElement);
      }
      audioElement.src = soundUrl;
      audioElement.currentTime = 0;
      const playPromise = audioElement.play();
      if (playPromise instanceof Promise) {
        playPromise.catch(error => console.warn("播放通知提示音失败:", error));
      }
    } catch (error) {
      console.warn("播放通知提示音异常:", error);
    }
  };

  const shouldShowToast = !isElectronClient;

  const navigateToTarget = (route?: string) => {
    if (!route) return;
    const target = route.trim();
    if (!target) return;
    if (/^https?:\/\//i.test(target)) {
      window.open(target, "_blank", "noopener");
      return;
    }
    router.push(target).catch((error: NavigationFailure | void) => {
      if (error) {
        console.warn("跳转通知路由失败:", error);
      }
    });
  };

  const markNotificationAsRead = async (
    detail: SystemNotificationDetail
  ): Promise<void> => {
    if (!detail.messageId) return;

    const payload: MarkReadPayload = {};
    if (detail.recipientId !== undefined) {
      payload.recipient_id = detail.recipientId;
    }
    if (detail.targetType) {
      payload.target_type = detail.targetType;
    }
    if (detail.targetId !== undefined) {
      const numeric = Number(detail.targetId);
      payload.target_id = Number.isNaN(numeric) ? detail.targetId : numeric;
    }

    try {
      await notifyRecordApi.markRead(detail.messageId, payload);
    } catch (error) {
      console.warn("标记通知已读失败:", error);
    }
  };

  const handler = ((event: Event) => {
    const detail = (event as CustomEvent<SystemNotificationDetail>).detail;
    if (!detail) return;

    const title =
      detail.title && detail.title.trim().length > 0
        ? detail.title
        : "系统通知";
    const message =
      detail.message && detail.message.trim().length > 0
        ? detail.message
        : "您有一条新的通知";

    let notificationInstance: ReturnType<typeof ElNotification> | undefined;

    if (shouldShowToast) {
      notificationInstance = ElNotification({
        title,
        message,
        duration: 6000,
        type: "info",
        onClick: () => {
          notificationInstance?.close();
          void markNotificationAsRead(detail);
          navigateToTarget(detail.route);
        }
      });
    }

    if (detail.sound) {
      playNotificationSound(detail.sound);
    }
  }) as EventListener;

  globalWindow.__notifyHandler__ = handler;
  window.addEventListener("systemNotification", handler);

  const electronIpc = (window as any).ipcRenderer;
  if (electronIpc && !globalWindow.__notifyIpcRegistered__) {
    electronIpc.on("notification-clicked", (_event: any, payload: any) => {
      if (!payload) return;
      const detail: SystemNotificationDetail = {
        title:
          typeof payload.title === "string" && payload.title.trim().length > 0
            ? payload.title
            : "系统通知",
        message:
          typeof payload.message === "string" &&
          payload.message.trim().length > 0
            ? payload.message
            : "您有一条新的通知",
        route: typeof payload.route === "string" ? payload.route : undefined,
        sound: typeof payload.sound === "string" ? payload.sound : undefined,
        messageId:
          typeof payload.messageId === "number" ? payload.messageId : undefined,
        recipientId:
          typeof payload.recipientId === "number"
            ? payload.recipientId
            : undefined,
        targetId: payload.targetId,
        targetType:
          typeof payload.targetType === "string"
            ? payload.targetType
            : undefined
      };
      void markNotificationAsRead(detail);
      navigateToTarget(detail.route);
    });

    electronIpc.on("show-html5-notification", (_event: any, payload: any) => {
      if (!payload) return;
      const title =
        typeof payload.title === "string" && payload.title.trim().length > 0
          ? payload.title
          : "系统通知";
      const messageText =
        typeof payload.body === "string" && payload.body.trim().length > 0
          ? payload.body
          : typeof payload.message === "string" &&
              payload.message.trim().length > 0
            ? payload.message
            : "您有一条新的通知";

      let htmlNotification: ReturnType<typeof ElNotification> | undefined;

      htmlNotification = ElNotification({
        title,
        message: messageText,
        duration: 6000,
        type: "info",
        onClick: () => {
          htmlNotification?.close();
          void markNotificationAsRead({
            title,
            message: messageText,
            route:
              typeof payload.route === "string" ? payload.route : undefined,
            sound:
              typeof payload.sound === "string" ? payload.sound : undefined,
            messageId:
              typeof payload.messageId === "number"
                ? payload.messageId
                : undefined,
            recipientId:
              typeof payload.recipientId === "number"
                ? payload.recipientId
                : undefined,
            targetId: payload.targetId,
            targetType:
              typeof payload.targetType === "string"
                ? payload.targetType
                : undefined
          });
          navigateToTarget(
            typeof payload.route === "string" ? payload.route : undefined
          );
        }
      });

      if (typeof payload.sound === "string" && payload.sound) {
        playNotificationSound(payload.sound);
      }
    });

    globalWindow.__notifyIpcRegistered__ = true;
  }
};

registerSystemNotificationHandler();

const ensureWebsocketConnected = () => {
  const token = getToken();
  if (token?.accessToken) {
    websocketClient.init();
  }
};

import Table from "@pureadmin/table";
// import PureDescriptions from "@pureadmin/descriptions";

// 引入重置样式
import "./style/reset.scss";
// 导入公共样式
import "./style/index.scss";
// 一定要在main.ts中导入tailwind.css，防止vite每次hmr都会请求src/style/index.scss整体css文件导致热更新慢的问题
import "./style/tailwind.css";
import "element-plus/dist/index.css";
// 导入字体图标
import "./assets/iconfont/iconfont.js";
import "./assets/iconfont/iconfont.css";

const app = createApp(App);

// 自定义指令
import * as directives from "@/directives";
Object.keys(directives).forEach(key => {
  app.directive(key, (directives as { [key: string]: Directive })[key]);
});

// 全局注册@iconify/vue图标库
import {
  IconifyIconOffline,
  IconifyIconOnline,
  FontIcon
} from "./components/ReIcon";
app.component("IconifyIconOffline", IconifyIconOffline);
app.component("IconifyIconOnline", IconifyIconOnline);
app.component("FontIcon", FontIcon);

// 全局注册按钮级别权限组件
import { Auth } from "@/components/ReAuth";
import { Perms } from "@/components/RePerms";
app.component("Auth", Auth);
app.component("Perms", Perms);

// 全局注册vue-tippy
import "tippy.js/dist/tippy.css";
import "tippy.js/themes/light.css";
import VueTippy from "vue-tippy";
app.use(VueTippy);

getPlatformConfig(app).then(async config => {
  setupStore(app);
  app.use(router);
  await router.isReady();
  ensureWebsocketConnected();
  injectResponsiveStorage(app, config);
  app.use(MotionPlugin).use(useElementPlus).use(Table);
  // .use(PureDescriptions)
  // .use(useEcharts);
  app.mount("#app").$nextTick(() => {
    postMessage({ payload: "removeLoading" }, "*");
  });
});
